package com.yc.rpc.core.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yc.rpc.core.Metadata;
import com.yc.rpc.core.YcRpcResponse;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;

/**
 * @author 冉野 E-mail:yangtianrui135@163.com
 * @version 创建时间：2021/7/14 10:28 AM
 */
@ChannelHandler.Sharable
public class NettyServerHandler extends ChannelInboundHandlerAdapter {


    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);

    private ApplicationContext context;

    public NettyServerHandler(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {


        ByteBuf buf = (ByteBuf) msg;
        Metadata metadata = null;
        String recieved = getMessage(buf);
        YcRpcResponse ycRpcResponse = new YcRpcResponse();
        try {
            metadata = JSON.parseObject(recieved, Metadata.class);
        } catch (Exception e) {
//            ycRpcResponse.setRequestId();
            ctx.writeAndFlush(Unpooled.buffer().writeBytes("{}".getBytes()));

            System.out.println("异常了---》》》》"+ recieved);
            return;
        }
        System.err.println("服务器接收到客户端消息：" + metadata.getClazz());
        Class<?> classType=Class.forName(metadata.getClazz());
        Object metadataObject = context.getBean(classType);


        Method method = metadataObject.getClass().getMethod(metadata.getMethod(), metadata.getParameterTypes());
        // 执行结果
        Object response = method.invoke(metadataObject, metadata.getParameters());

        ycRpcResponse.setData(JSONObject.toJSONString(response));
        ycRpcResponse.setRequestId(metadata.getRequestId());

        logger.info("服务端返回结果：[{}]", JSONObject.toJSONString(ycRpcResponse));

        // 向客户端发送消息
        ctx.writeAndFlush(Unpooled.buffer().writeBytes((JSONObject.toJSONString(ycRpcResponse)+ "\r\n").getBytes()));




    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        // 打印 OutboundHandlerC -> OutboundHandlerB  ->  OutboundHandlerA 从尾部开始往前找 outbound
        ctx.channel().writeAndFlush("write in InBoundHandlerC");
        // 只打印 OutboundHandlerB  ->  OutboundHandlerA 从当前 handler 往前找 outbound
        // ctx.writeAndFlush("write in InBoundHandlerC");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        cause.printStackTrace();
        logger.error("服务器发生异常-------------->>");
        ctx.close();
    }

    private String getMessage(ByteBuf buf) {

        byte[] con = new byte[buf.readableBytes()];
        buf.readBytes(con);
        try {
            return new String(con, "UTF8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}
